home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #ifndef NOSTDLIB_H
- #include <stdlib.h>
- #endif
- #ifndef NOUNISTD_H
- #include <unistd.h>
- #endif
- #include "symbol.h"
- #include "code.h"
- #include "math.tab.h"
- #include "fudgit.h"
- #include "head.h"
-
- extern char Ft_Format[];
- extern char Ft_TFormat[];
- extern FILE *Ft_Outprint;
-
- #undef DEBUG
-
- #ifdef DEBUG
- #define CODE(a) fprintf(stderr, "Run: %s\n", a)
- #define PNUM(a) fprintf(stderr, "Run: %g\n ", (double)a)
- #else
- #define CODE(a)
- #define PNUM(a)
- #endif
-
- typedef struct Frame {
- Symbol *sp;
- Inst *retpc;
- Datum *argn;
- int nargs;
- } Frame;
-
- int Ft_Indef = 0;
- int Ft_Inproto = 0;
- int Ft_Inauto = 0;
- int Ft_Inbrace = 0;
- Inst *Ft_Progp;
- Inst *Ft_Progbase;
-
- static int Index = ERRR;
- static Inst *prog;
- static Inst *pc;
- static int Returning = 0;
- static int Break = 0;
- static Datum *stack;
- static Datum *stackp;
- static Frame *frame;
- static Frame *frp;
-
- static void cleanfrp(int num), ret(void);
- static double *getarg(void);
- static Inst *checkargs(Inst *start, Frame *frpp);
- static char *makename(Symbol *sp);
-
- void Ft_cleanframe(void), Ft_matherror(char *s1, char *s2, int lino);
- Code Ft_vecexec(int size);
-
- extern char *strcat (char *, const char *);
- extern void Ft_free_dvector (double *v, int nl, int nh);
-
- void Ft_resetprog(void)
- {
- Ft_Progbase = prog;
- }
-
- void Ft_resetindex(void)
- {
- Index = ERRR;
- }
-
- void Ft_initstacks(void)
- {
- stack = (Datum *)malloc((unsigned)((NSTACK+2) * sizeof(Datum)));
- if (stack == (Datum *)NULL) {
- fputs("Math error: Fatal error on stack allocation.\n", stderr);
- exit(1);
- }
- prog = (Inst *)malloc((unsigned)((NPROG+2) * sizeof(Inst)));
- if (prog == (Inst *)NULL) {
- fputs("Math error: Fatal error on stack allocation.\n", stderr);
- exit(1);
- }
- frame = (Frame *)malloc((unsigned)((NFRAME+2) * sizeof(Frame)));
- if (frame == (Frame *)NULL) {
- fputs("Math error: Fatal error on stack allocation.\n", stderr);
- exit(1);
- }
- frame[0].argn = stack;
- frame[0].nargs = 0;
- frame[0].sp = 0;
- frp = ++frame;
- Ft_Progbase = prog;
- }
-
- int Ft_funcprocnotdef(void)
- {
- if (Ft_Progbase == prog)
- return(1);
- return(0);
- }
-
- void Ft_initcode(void)
- {
- CODE("initcode");
- Ft_Progp = Ft_Progbase;
- Ft_cleanframe();
- stackp = stack;
- Returning = 0;
- Break = 0;
- }
-
- #ifndef MACROPOP
- Code Ft_push(Datum d)
- {
- CODE("push");
- if (stackp >= &stack[NSTACK]) {
- Ft_matherror("Stack overflow.", NULL, 0);
- }
- *stackp = d;
- stackp++;
- }
- #else
- #define Ft_push(a) (*stackp++ = a)
- #endif
-
- /* solving the problem for returning function on execute */
- Code Ft_nullpop(void)
- {
- CODE("nullpop");
- if (stackp <= stack) {
- Ft_matherror("Stack underflow.", NULL, 0);
- }
- stackp--;
- }
-
- #ifndef MACROPOP
- Datum Ft_pop(void)
- {
- CODE("pop");
- if (stackp <= stack) {
- Ft_matherror("Stack underflow.", NULL, 0);
- }
- stackp--;
- return(*stackp);
- }
- #else
- #define Ft_pop() (*(--stackp))
- #endif
-
- Inst *Ft_code(Inst f)
- {
- Inst *oProgp = Ft_Progp;
-
- if (Ft_Progp >= &prog[NPROG]) {
- Ft_matherror("Instruction code overflow.", NULL, 0);
- }
- *Ft_Progp = f;
- Ft_Progp++;
- return(oProgp);
- }
-
- Inst *Ft_dblcode(double d)
- {
- Inst *oProgp = Ft_Progp;
- #ifndef DALIGN
- double *dp = (double *)Ft_Progp;
- #endif
- if (Ft_Progp >= &prog[NPROG]) {
- Ft_matherror("Instruction code overflow.", NULL, 0);
- }
- #ifndef DALIGN
- *dp = d;
- #else
- bcopy((void *)&d, (void *)Ft_Progp, sizeof(double));
- #endif
- Ft_Progp += (sizeof(double)/sizeof(Inst *));
- return(oProgp);
- }
-
- Code Ft_parloop(void)
- {
- extern double *Ft_Param;
-
- Ft_vecexec((int)(*Ft_Param));
- }
-
- Code Ft_vecloop(void)
- {
- extern double *Ft_Data;
-
- Ft_vecexec((int)(*Ft_Data));
- }
-
- /* called by loops */
- Code Ft_vecexec(int size)
- {
- register Inst *pp;
- Inst *basepc;
- extern int Index;
-
- CODE("vexecute at");
- PNUM((int)(pc-prog));
- if (size == 0) {
- Ft_matherror("Null size vector!", NULL, 0);
- }
- basepc = pc;
-
- /* !Returning and !Break do not have to be checked for */
- /* since there is no statement in vexec */
- for (Index = 1;Index <= size; Index++) {
- pc = basepc;
- while (*pc) {
- pp = pc++;
- (void) (*(*pp))();
- }
- }
- /* Park Index variable */
- Index = ERRR;
- /* place pc after loop STOP */
- pc++;
- }
-
- void Ft_execute(Inst *p)
- {
- register Inst *pp;
-
- CODE("execute at");
- PNUM((int)(p-prog));
- for (pc = p; *pc != STOP && !Returning && !Break; ) {
- pp = pc++;
- (void) (*(*pp))();
- }
- }
-
- Code Ft_varpush(void)
- {
- Datum d;
-
- CODE("varpush");
- d.sym = (Symbol *)(*pc);
- pc++;
- CODE(d.sym->name);
- Ft_push(d);
- }
-
- Code Ft_strpush(void)
- {
- Datum d;
-
- CODE("strpush");
- d.str = ((Symbol *)*pc)->u.str;
- pc++;
- CODE(d.str);
- Ft_push(d);
- }
-
- Code Ft_constpush(void)
- {
- Datum d;
- #ifndef DALIGN
- double *dp = (double *)pc;
-
- CODE("constpush");
- d.val = *dp;
- #else
-
- CODE("constpush");
- bcopy((void *)pc, (void *)&d.val, sizeof(double));
- #endif
- pc += (sizeof(double)/sizeof(Inst *));
- PNUM(d.val);
- PNUM(d.val);
- Ft_push(d);
- }
-
- Code Ft_negate(void)
- {
- Datum d;
-
- CODE("negate");
- d = Ft_pop();
- d.val = -d.val;
- Ft_push(d);
- }
-
- Code Ft_strsub(void)
- {
- static char diff[TOKENSIZE+4];
- Datum d1, d2;
- register char *cp1, *cp2;
-
- CODE("strsub");
- d2 = Ft_pop();
- d1 = Ft_pop();
- strcpy(diff, d1.str);
- d1.str = cp1 = diff;
- cp2 = d2.str;
- while (*cp1)
- cp1++;
- while (*cp2)
- cp2++;
- while (*cp1 == *cp2 || *cp2 == '?') {
- *cp1 = '\0';
- cp1--; cp2--;
- if (cp1 < diff || cp2 < d2.str)
- break;
- }
- Ft_push(d1);
- }
-
- Code Ft_stradd(void)
- {
- static char total[TOKENSIZE+4];
- Datum d1, d2;
-
- CODE("stradd");
- d2 = Ft_pop();
- d1 = Ft_pop();
- if (strlen(d1.str) + strlen(d2.str) > TOKENSIZE) {
- Ft_matherror("String addition: Result too long.", NULL, 0);
- }
- if (d2.str != total) {
- strcpy(total, d1.str);
- strcat(total, d2.str);
- }
- else {
- char tmp[TOKENSIZE+4];
-
- strcpy(tmp, d2.str);
- strcpy(total, d1.str);
- strcat(total, tmp);
- }
- d1.str = total;
- Ft_push(d1);
- }
-
- Code Ft_add(void)
- {
- Datum d1, d2;
-
- CODE("add");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val += d2.val;
- Ft_push(d1);
- }
-
- Code Ft_sub(void)
- {
- Datum d1, d2;
-
- CODE("sub");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val -= d2.val;
- Ft_push(d1);
- }
-
- Code Ft_mul(void)
- {
- Datum d1, d2;
-
- CODE("mul");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val *= d2.val;
- Ft_push(d1);
- }
-
- Code Ft_div(void)
- {
- Datum d1, d2;
- extern int Ft_Check;
-
- CODE("div");
- d2 = Ft_pop();
- if (d2.val == 0.0 && Ft_Check & INF_CHK) {
- Ft_matherror("Division by zero.", NULL, 0);
- }
- d1 = Ft_pop();
- d1.val /= d2.val;
- Ft_push(d1);
- }
-
- Code Ft_modulo(void)
- {
- Datum d1, d2;
- int tmp1, tmp2;
- extern int Ft_Check;
-
- CODE("modulo");
- d2 = Ft_pop();
- d1 = Ft_pop();
- if (d2.val == 0.0 && Ft_Check & INF_CHK) {
- Ft_matherror("Modulo division by zero.", NULL, 0);
- }
- tmp1 = d1.val;
- tmp2 = d2.val;
- d1.val = tmp1%tmp2;
- Ft_push(d1);
- }
-
- Code Ft_extcall(void)
- {
- Datum d;
- Symbol *sym;
- double dblvec[MATHMAXARG];
- void *ptrvec[MATHMAXARG];
- int ino, argno, type;
- char *tvec;
-
- CODE("pointer");
- sym = (Symbol *) *pc;
- pc++;
- CODE("number");
- argno = (int) *pc;
- pc++;
- if (argno >= MATHMAXARG)
- Ft_matherror("%s: Too many arguments (%d).", sym->name, argno);
- tvec = sym->size.vals; /* types stored there */
- for (ino=argno;ino > 0;ino--) {
- d = Ft_pop();
- type = (int) d.val;
- d = Ft_pop();
- if (!tvec[0])
- Ft_matherror("%s: Too many arguments (%d required).",
- sym->name, (argno-ino));
- switch(*tvec) {
- case PROTO_VAL:
- if (type != NUMBER)
- Ft_matherror("%s: Argument %d not an expr.",
- sym->name, ino);
- dblvec[ino-1] = d.val;
- ptrvec[ino-1] = (void *) (dblvec+ino-1);
- break;
- case PROTO_VEC:
- if (type != VEC)
- Ft_matherror("%s: Argument %d not a VEC.", sym->name, ino);
- ptrvec[ino-1] = (void *) (d.sym->u.vec + 1);
- break;
- case PROTO_PAR:
- if (type != PARAM)
- Ft_matherror("%s: Argument %d not a PARAM.", sym->name, ino);
- ptrvec[ino-1] = (void *)(d.sym->u.vec + 1);
- break;
- case PROTO_STR:
- if (type != STRVAR)
- Ft_matherror("%s: Argument %d not a String.",
- sym->name, ino);
- ptrvec[ino-1] = (void *)d.sym->u.str;
- break;
- default:
- Ft_matherror("%s: Unknown type in definition.", sym->name, 0);
- }
- tvec++;
- }
- if (tvec[0])
- Ft_matherror("%s: Not enough arguments (%d).", sym->name, argno);
- if (sym->type == EFUNCSYM) {
- d.val = ( *(double (*)(double *, ...)) sym->u.ptr) (
- ptrvec[0], ptrvec[1], ptrvec[2], ptrvec[3], ptrvec[4],
- ptrvec[5], ptrvec[6], ptrvec[7], ptrvec[8], ptrvec[9],
- ptrvec[10], ptrvec[11], ptrvec[12], ptrvec[13], ptrvec[14],
- ptrvec[15], ptrvec[16], ptrvec[17], ptrvec[18], ptrvec[19],
- ptrvec[20], ptrvec[21], ptrvec[22], ptrvec[23], ptrvec[24],
- ptrvec[25], ptrvec[26], ptrvec[27], ptrvec[28], ptrvec[29],
- ptrvec[30], ptrvec[31], ptrvec[32], ptrvec[33], ptrvec[34]);
- Ft_push(d);
- } else {
- (void) ( *(double (*)(double *, ...))sym->u.ptr) (
- ptrvec[0], ptrvec[1], ptrvec[2], ptrvec[3], ptrvec[4],
- ptrvec[5], ptrvec[6], ptrvec[7], ptrvec[8], ptrvec[9],
- ptrvec[10], ptrvec[11], ptrvec[12], ptrvec[13], ptrvec[14],
- ptrvec[15], ptrvec[16], ptrvec[17], ptrvec[18], ptrvec[19],
- ptrvec[20], ptrvec[21], ptrvec[22], ptrvec[23], ptrvec[24],
- ptrvec[25], ptrvec[26], ptrvec[27], ptrvec[28], ptrvec[29],
- ptrvec[30], ptrvec[31], ptrvec[32], ptrvec[33], ptrvec[34]);
- }
- }
-
- Code Ft_bltin0str(void)
- {
- Datum d;
-
- CODE("builtin0str");
- CODE("pointer");
- d.str = (*(char *(*)(void))(*pc))();
- pc++;
- Ft_push(d);
- }
-
- Code Ft_bltin0(void)
- {
- Datum d;
-
- CODE("builtin0");
- CODE("pointer");
- d.val = (*(double (*)(void))(*pc))();
- pc++;
- Ft_push(d);
- }
-
- Code Ft_bltin1(void)
- {
- Datum d;
-
- CODE("builtin1");
- d = Ft_pop();
- CODE("pointer");
- d.val = (*(double (*)(double))(*pc))(d.val);
- pc++;
- Ft_push(d);
- }
-
- Code Ft_bltin1vec(void)
- {
- Datum d;
-
- CODE("builtin1vec");
- d = Ft_pop();
- CODE("pointer");
- d.val = (*(double (*)(double *))(*pc))(d.sym->u.vec);
- pc++;
- Ft_push(d);
- }
-
- Code Ft_bltin2(void)
- {
- Datum d1, d2;
-
- CODE("bltin2");
- d2 = Ft_pop();
- d1 = Ft_pop();
- CODE("pointer");
- d1.val = (*(double (*)(double, double))(*pc))(d1.val, d2.val);
- pc++;
- Ft_push(d1);
- }
-
- Code Ft_bltin1str(void)
- {
- Datum d;
-
- CODE("bltin1str");
- d = Ft_pop();
- CODE("pointer");
- d.str = (*(char *(*)(char *))(*pc))(d.str);
- pc++;
- Ft_push(d);
- }
-
- Code Ft_bltin2str(void)
- {
- Datum d1, d2;
-
- CODE("bltin2str");
- d2 = Ft_pop();
- d1 = Ft_pop();
- CODE("pointer");
- d1.str = (*(char *(*)(char *, char *))(*pc))(d1.str, d2.str);
- pc++;
- Ft_push(d1);
- }
-
- Code Ft_strbltin2(void)
- {
- Datum d1, d2;
-
- CODE("strbltin2");
- d2 = Ft_pop();
- d1 = Ft_pop();
- CODE("pointer");
- d1.val = (*(double (*)(char *, char *))(*pc))(d1.str, d2.str);
- pc++;
- Ft_push(d1);
- }
-
- Code Ft_power(void)
- {
- Datum d1, d2;
- extern double Ft_Pow(double x, double y);
-
- CODE("power");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = Ft_Pow(d1.val, d2.val);
- Ft_push(d1);
- }
-
- Code Ft_eeval(void)
- {
- Datum d1, d2;
- register int index;
-
- CODE("eeval");
- d1 = Ft_pop();
- /*********************
- if (d1.sym->type != VEC && d1.sym->type != PARAM) {
- Ft_matherror("%s: Not a vector or parameter.", d1.sym->name, 0);
- }
- **********************/
- d2 = Ft_pop();
- index = (int) d2.val;
- if (index < 1 || index > d1.sym->size.val) {
- Ft_matherror("%s: Index %d out of range.", d1.sym->name, index);
- }
- d2.val = d1.sym->u.vec[index];
- Ft_push(d2);
- }
-
- Code Ft_postieval(void)
- {
- Datum d1, d2;
-
- CODE("postieval");
- d1 = Ft_pop();
- if (d1.sym->type == VAR || d1.sym->type == BLTINVAR) {
- d2.val = d1.sym->u.val;
- d1.sym->u.val += 1.0;
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == UNDEFVAR) {
- Ft_matherror("%s: Unassigned variable.", d1.sym->name, 0);
- }
- Ft_matherror("%s: Not a regular variable.", d1.sym->name, 0);
- }
-
- Code Ft_postdeval(void)
- {
- Datum d1, d2;
-
- CODE("postdeval");
- d1 = Ft_pop();
- if (d1.sym->type == VAR || d1.sym->type == BLTINVAR) {
- d2.val = d1.sym->u.val;
- d1.sym->u.val -= 1.0;
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == UNDEFVAR) {
- Ft_matherror("%s: Unassigned variable.", d1.sym->name, 0);
- }
- Ft_matherror("%s: Not a regular variable.", d1.sym->name, 0);
- }
-
- Code Ft_preieval(void)
- {
- Datum d;
-
- CODE("preieval");
- d = Ft_pop();
- if (d.sym->type == VAR || d.sym->type == BLTINVAR) {
- d.sym->u.val += 1.0;
- d.val = d.sym->u.val;
- Ft_push(d);
- return;
- }
- if (d.sym->type == UNDEFVAR) {
- Ft_matherror("%s: Unassigned variable.", d.sym->name, 0);
- }
- Ft_matherror("%s: Not a regular variable.", d.sym->name, 0);
- }
-
- Code Ft_predeval(void)
- {
- Datum d;
-
- CODE("predeval");
- d = Ft_pop();
- if (d.sym->type == VAR || d.sym->type == BLTINVAR) {
- d.sym->u.val -= 1.0;
- d.val = d.sym->u.val;
- Ft_push(d);
- return;
- }
- if (d.sym->type == UNDEFVAR) {
- Ft_matherror("%s: Unassigned variable.", d.sym->name, 0);
- }
- Ft_matherror("%s: Not a regular variable.", d.sym->name, 0);
- }
-
- Code Ft_eval(void)
- {
- extern int Index;
- register int type;
- Datum d;
-
- CODE("eval");
- d = Ft_pop();
- type = d.sym->type;
- if (type == VEC || type == PARAM) {
- if (Index == ERRR) {
- Ft_matherror("%s: Illegal vector assignment.", d.sym->name, 0);
- }
- d.val = d.sym->u.vec[Index];
- Ft_push(d);
- return;
- }
- if (type >= VAR && type <= BLTINCONST) {
- d.val = d.sym->u.val;
- Ft_push(d);
- return;
- }
- if (type == UNDEFVEC) {
- Ft_matherror("%s: Unassigned vector.", d.sym->name, 0);
- }
- if (type == UNDEFVAR) {
- Ft_matherror("%s: Unassigned variable.", d.sym->name, 0);
- }
- Ft_matherror("%s: Not a regular variable.", d.sym->name, 0);
- }
-
- Code Ft_streval(void)
- {
- Datum d;
-
- CODE("streval");
- d = Ft_pop();
- if (d.sym->type >= STRVAR && d.sym->type <= BLTINSTRCONST) {
- d.str = d.sym->u.str;
- Ft_push(d);
- return;
- }
- if (d.sym->type == UNDEFSTRVAR) {
- Ft_matherror("%s: Unassigned string variable.", d.sym->name, 0);
- }
- Ft_matherror("%s: Not a regular string variable.", d.sym->name, 0);
- }
-
- Code Ft_eassign(void)
- {
- Datum d1, d2, d3;
- int index;
-
- CODE("eassign");
- d1 = Ft_pop();
- if (d1.sym->type != VEC && d1.sym->type != PARAM
- && d1.sym->type != UNDEFVEC) {
- Ft_matherror("%s: Illegal element assignment.", d1.sym->name, 0);
- }
- d2 = Ft_pop();
- d3 = Ft_pop();
- index = (int)d3.val;
- if (index < 1 || index > d1.sym->size.val) {
- Ft_matherror("%s: Index %d out of range.", d1.sym->name, index);
- }
- d1.sym->u.vec[index] = d2.val;
- if (d1.sym->type == UNDEFVEC) {
- d1.sym->type = VEC;
- }
- Ft_push(d2);
- }
-
- Code Ft_assign(void)
- {
- Datum d1, d2;
-
- CODE("assign");
- d1 = Ft_pop();
- d2 = Ft_pop();
- if (d1.sym->type == VEC || d1.sym->type == PARAM
- || d1.sym->type == UNDEFVEC) {
- if (Index == ERRR) { /* assignment from vexecute() only */
- Ft_matherror("%s: Illegal vector assignment.", d1.sym->name, 0);
- }
- d1.sym->u.vec[Index] = d2.val;
- if (d1.sym->type == UNDEFVEC) {
- d1.sym->type = VEC;
- }
- }
- else if (d1.sym->type == VAR || d1.sym->type == BLTINVAR) {
- d1.sym->u.val = d2.val;
- }
- else if (d1.sym->type == UNDEFVAR) {
- d1.sym->u.val = d2.val;
- d1.sym->type = VAR;
- }
- else {
- Ft_matherror("%s: Assignment to non-variable.", d1.sym->name, 0);
- }
- Ft_push(d2);
- }
-
- Code Ft_strassign(void)
- {
- Datum d1, d2;
-
- CODE("strassign");
- d1 = Ft_pop();
- d2 = Ft_pop();
- if (d1.sym->type != STRVAR && d1.sym->type != UNDEFSTRVAR &&
- d1.sym->type != BLTINSTRVAR) {
- Ft_matherror("%s: Assignment to non-string variable.", d1.sym->name, 0);
- }
- if (d1.sym->type != UNDEFSTRVAR) {
- free(d1.sym->u.str);
- }
- else {
- d1.sym->type = STRVAR;
- }
- if ((d1.sym->u.str = (char *)malloc(strlen(d2.str) + 1)) == (char *)NULL) {
- Ft_matherror("Allocation error in string assignment.", NULL, 0);
- }
- strcpy(d1.sym->u.str, d2.str);
- Ft_push(d2);
- }
-
- Code Ft_le(void)
- {
- Datum d1, d2;
-
- CODE("le");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) (d1.val <= d2.val);
- Ft_push(d1);
- }
-
- Code Ft_lt(void)
- {
- Datum d1, d2;
-
- CODE("lt");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) (d1.val < d2.val);
- Ft_push(d1);
- }
-
-
- Code Ft_ge(void)
- {
- Datum d1, d2;
-
- CODE("ge");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) (d1.val >= d2.val);
- Ft_push(d1);
- }
-
- Code Ft_gt(void)
- {
- Datum d1, d2;
-
- CODE("gt");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) (d1.val > d2.val);
- Ft_push(d1);
- }
-
- Code Ft_ne(void)
- {
- Datum d1, d2;
-
- CODE("ne");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) (d1.val != d2.val);
- Ft_push(d1);
- }
-
- Code Ft_eq(void)
- {
- Datum d1, d2;
-
- CODE("eq");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) (d1.val == d2.val);
- Ft_push(d1);
- }
-
- Code Ft_streq(void)
- {
- Datum d1, d2;
-
- CODE("eq");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) (strcmp(d1.str, d2.str) == 0);
- Ft_push(d1);
- }
-
- Code Ft_strne(void)
- {
- Datum d1, d2;
-
- CODE("eq");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) (strcmp(d1.str, d2.str) != 0);
- Ft_push(d1);
- }
-
- Code Ft_and(void)
- {
- Datum d1, d2;
-
- CODE("and");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) ((d1.val != 0.0) && (d2.val != 0.0));
- Ft_push(d1);
- }
-
- Code Ft_or(void)
- {
- Datum d1, d2;
-
- CODE("or");
- d2 = Ft_pop();
- d1 = Ft_pop();
- d1.val = (double) ((d1.val != 0.0) || (d2.val != 0.0));
- Ft_push(d1);
- }
-
- Code Ft_not(void)
- {
- Datum d;
-
- CODE("not");
- d = Ft_pop();
- d.val = (double) (d.val == 0.0);
- Ft_push(d);
- }
-
- Code Ft_whilecode(void)
- {
- Datum d;
- Inst *savepc = pc; /* pc is the next instruction */
-
- CODE("whilecode");
- Break = 0;
- Ft_execute(savepc+2); /* the condition */
- d = Ft_pop();
- while (d.val) {
- Ft_execute(*((Inst **)(savepc))); /* the body */
- if (Break || Returning)
- break;
- Ft_execute(savepc + 2);
- d = Ft_pop();
- }
- if (!Returning)
- pc = *((Inst **)(savepc+1));
- }
-
- Code Ft_forcode(void)
- {
- Datum d;
- Inst *savepc = pc; /* pc is the next to for itself */
-
- CODE("forcode");
- Break = 0;
- Ft_execute(savepc+4); /* assignments */
- Ft_execute(*((Inst **)savepc)); /* the condition */
- d = Ft_pop();
- while (d.val) {
- Ft_execute(*((Inst **)(savepc+2))); /* the body-statement */
- if (Break || Returning)
- break;
- Ft_execute(*(Inst **)(savepc+1)); /* the expression list */
- Ft_execute(*(Inst **)savepc); /* the conditional expression */
- d = Ft_pop();
- }
- if (!Returning)
- pc = *((Inst **)(savepc+3));
- }
-
- Code Ft_ifcode(void)
- {
- Datum d;
- Inst *savepc = pc;
-
- CODE("ifcode");
- Ft_execute(savepc+3);
- d = Ft_pop();
- if (d.val)
- Ft_execute(*((Inst **) (savepc)));
- else if (*((Inst **)(savepc+1)))
- Ft_execute(*((Inst **) (savepc+1)));
- if (!Returning)
- pc = *((Inst**)(savepc+2));
- }
-
- Code Ft_linprnl(void)
- {
- CODE("linprnl");
- fputc('\n', stdout);
- fflush(stdout);
- }
-
- Code Ft_linprexpr(void)
- {
- Datum d;
-
- CODE("linprexpr");
- d = Ft_pop();
- fprintf(stdout, Ft_Format, d.val);
- fputc('\t', stdout);
- fflush(stdout);
- }
-
- Code Ft_linprstr(void)
- {
- Datum d;
-
- CODE("linprstr");
- d = Ft_pop();
- fputs(d.str, stdout);
- fflush(stdout);
- }
-
- Code Ft_prstr(void)
- {
- Datum d;
-
- CODE("prstr");
- d = Ft_pop();
- fputs(d.str, Ft_Outprint);
- fflush(Ft_Outprint);
- }
-
- Code Ft_prexpr(void)
- {
- Datum d;
-
- CODE("prexpr");
- d = Ft_pop();
- fprintf(Ft_Outprint, Ft_Format, d.val);
- fputc('\t', Ft_Outprint);
- fflush(Ft_Outprint);
- }
-
- Code Ft_addassign(void)
- {
- Datum d1, d2;
-
- CODE("addassign");
- d1 = Ft_pop();
- d2 = Ft_pop();
- if (d1.sym->type == VEC || d1.sym->type == PARAM) {
- if (Index == ERRR) { /* assignment from vexecute() only */
- Ft_matherror("%s: Illegal vector assignment.", d1.sym->name, 0);
- }
- d2.val = (d1.sym->u.vec[Index] += d2.val);
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == VAR || d1.sym->type == BLTINVAR) {
- d2.val = (d1.sym->u.val += d2.val);
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == UNDEFVAR || d1.sym->type == UNDEFVEC) {
- Ft_matherror("%s: Unassigned variable.", d1.sym->name, 0);
- }
- Ft_matherror("%s: Assignment to non-variable.", d1.sym->name, 0);
- }
-
- Code Ft_mulassign(void)
- {
- Datum d1, d2;
-
- CODE("mulassign");
- d1 = Ft_pop();
- d2 = Ft_pop();
- if (d1.sym->type == VEC || d1.sym->type == PARAM) {
- if (Index == ERRR) { /* assignment from vexecute() only */
- Ft_matherror("%s: Illegal vector assignment.", d1.sym->name, 0);
- }
- d2.val = (d1.sym->u.vec[Index] *= d2.val);
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == VAR || d1.sym->type == BLTINVAR) {
- d2.val = (d1.sym->u.val *= d2.val);
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == UNDEFVAR || d1.sym->type == UNDEFVEC) {
- Ft_matherror("%s: Unassigned variable.", d1.sym->name, 0);
- }
- Ft_matherror("%s: Assignment to non-variable.", d1.sym->name, 0);
- }
-
- Code Ft_divassign(void)
- {
- Datum d1, d2;
- extern int Ft_Check;
-
- CODE("divassign");
- d1 = Ft_pop();
- d2 = Ft_pop();
- if (d1.sym->type == VEC || d1.sym->type == PARAM) {
- if (Index == ERRR) { /* assignment from vexecute() only */
- Ft_matherror("%s: Illegal vector assignment.", d1.sym->name, 0);
- }
- if (d2.val == 0.0 && Ft_Check & INF_CHK) {
- Ft_matherror("%s: Division by zero.", d1.sym->name, 0);
- }
- d2.val = (d1.sym->u.vec[Index] /= d2.val);
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == VAR || d1.sym->type == BLTINVAR) {
- if (d2.val == 0.0 && Ft_Check & INF_CHK) {
- Ft_matherror("%s: Division by zero.", d1.sym->name, 0);
- }
- d2.val = (d1.sym->u.val /= d2.val);
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == UNDEFVAR || d1.sym->type == UNDEFVEC) {
- Ft_matherror("%s: Unassigned variable.", d1.sym->name, 0);
- }
- Ft_matherror("%s: Assignment to non-variable.", d1.sym->name, 0);
- }
-
- Code Ft_subassign(void)
- {
- Datum d1, d2;
-
- CODE("subassign");
- d1 = Ft_pop();
- d2 = Ft_pop();
- if (d1.sym->type == VEC || d1.sym->type == PARAM) {
- if (Index == ERRR) { /* assignment from vexecute() only */
- Ft_matherror("%s: Illegal vector assignment.", d1.sym->name, 0);
- }
- d2.val = (d1.sym->u.vec[Index] -= d2.val);
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == VAR || d1.sym->type == BLTINVAR) {
- d2.val = (d1.sym->u.val -= d2.val);
- Ft_push(d2);
- return;
- }
- if (d1.sym->type == UNDEFVAR || d1.sym->type == UNDEFVEC) {
- Ft_matherror("%s: Unassigned variable.", d1.sym->name, 0);
- }
- Ft_matherror("%s: Assignment to non-variable.", d1.sym->name, 0);
- }
-
- Code Ft_eaddassign(void)
- {
- Datum d1, d2, d3;
- int index;
-
- CODE("eaddassign");
- d1 = Ft_pop();
- if (d1.sym->type != VEC && d1.sym->type != PARAM) {
- if (d1.sym->type == UNDEFVAR || d1.sym->type == UNDEFVEC)
- Ft_matherror("%s: Unassigned vector.", d1.sym->name, 0);
- else
- Ft_matherror("%s: Illegal element assignment.", d1.sym->name, 0);
- }
- d2 = Ft_pop();
- d3 = Ft_pop();
- index = (int)d3.val;
- if (index < 1 || index > d1.sym->size.val) {
- Ft_matherror("%s: Index %d out of range.", d1.sym->name, index);
- }
- d2.val = (d1.sym->u.vec[index] += d2.val);
- Ft_push(d2);
- }
-
- Code Ft_emulassign(void)
- {
- Datum d1, d2, d3;
- int index;
-
- CODE("emulassign");
- d1 = Ft_pop();
- if (d1.sym->type != VEC && d1.sym->type != PARAM) {
- if (d1.sym->type == UNDEFVAR || d1.sym->type == UNDEFVEC)
- Ft_matherror("%s: Unassigned vector.", d1.sym->name, 0);
- else
- Ft_matherror("%s: Illegal element assignment.", d1.sym->name, 0);
- }
- d2 = Ft_pop();
- d3 = Ft_pop();
- index = (int)d3.val;
- if (index < 1 || index > d1.sym->size.val) {
- Ft_matherror("%s: Index %d out of range.", d1.sym->name, index);
- }
- d2.val = (d1.sym->u.vec[index] *= d2.val);
- Ft_push(d2);
- }
-
- Code Ft_edivassign(void)
- {
- Datum d1, d2, d3;
- int index;
- extern int Ft_Check;
-
- CODE("edivassign");
- d1 = Ft_pop();
- if (d1.sym->type != VEC && d1.sym->type != PARAM) {
- if (d1.sym->type == UNDEFVAR || d1.sym->type == UNDEFVEC)
- Ft_matherror("%s: Unassigned vector.", d1.sym->name, 0);
- else
- Ft_matherror("%s: Illegal element assignment.", d1.sym->name, 0);
- }
- d2 = Ft_pop();
- if (d2.val == 0.0 && Ft_Check & INF_CHK) {
- Ft_matherror("%s: Division by zero.", d1.sym->name, 0);
- }
- d3 = Ft_pop();
- index = (int)d3.val;
- if (index < 1 || index > d1.sym->size.val) {
- Ft_matherror("%s: Index %d out of range.", d1.sym->name, index);
- }
- d2.val = (d1.sym->u.vec[index] /= d2.val);
- Ft_push(d2);
- }
-
- Code Ft_esubassign(void)
- {
- Datum d1, d2, d3;
- int index;
-
- CODE("esubassign");
- d1 = Ft_pop();
- if (d1.sym->type != VEC && d1.sym->type != PARAM) {
- if (d1.sym->type == UNDEFVAR || d1.sym->type == UNDEFVEC)
- Ft_matherror("%s: Unassigned vector.", d1.sym->name, 0);
- else
- Ft_matherror("%s: Illegal element assignment.", d1.sym->name, 0);
- }
- d2 = Ft_pop();
- d3 = Ft_pop();
- index = (int)d3.val;
- if (index < 1 || index > d1.sym->size.val) {
- Ft_matherror("%s: Index %d out of range.", d1.sym->name, index);
- }
- d2.val = (d1.sym->u.vec[index] -= d2.val);
- Ft_push(d2);
- }
-
- Code Ft_breakit(void)
- {
- CODE("breakit");
- Break = 1;
- }
-
- Code Ft_chkfunc(int type, Symbol *sp)
- {
- if (sp->type == UNDEFVAR || sp->type == FUNCSYM || sp->type == PROCSYM) {
- sp->type = type;
- }
- else {
- Ft_matherror("%s: Symbol already defined and protected.", sp->name, 0);
- }
- }
-
- Code Ft_define(Symbol *sp)
- {
- sp->u.defn = Ft_Progbase;
- Ft_Progbase = Ft_Progp;
- }
-
- Code Ft_call(void)
- {
- Symbol *sp = (Symbol *)pc[0];
- Inst *pp;
-
- CODE("call");
- CODE(sp->name);
- if (frp++ >= &frame[NFRAME-1]) {
- frp--;
- Ft_matherror("%s: Call too deeply nested.", sp->name, 0);
- }
- frp->sp = sp;
- frp->nargs = (int)pc[1];
- PNUM(frp->nargs);
- frp->retpc = pc+2; /* return at second next address */
- frp->argn = stackp - 1;
- pp = checkargs(sp->u.defn, frp);
- Ft_execute(pp);
- Returning = 0;
- }
-
- Code Ft_boost(void) /* a lot of self-consistency implied... */
- {
- CODE("boost");
- PNUM((int)pc[0]);
- frp->nargs += (int) *pc++;
- frp->argn = stackp-1;
- }
-
- Code Ft_restore(void)
- {
- CODE("restore");
- PNUM((int)pc[0]);
- cleanfrp((int)*pc++);
- }
-
- void Ft_cleanframe(void)
- {
- while (frp != frame) {
- cleanfrp(ALL);
- frp--;
- }
- }
-
- static void cleanfrp(int num)
- {
- Symbol *sp;
-
- if (num == ALL) {
- num = frp->nargs;
- }
- else if (num > frp->nargs) {
- Ft_matherror("Impossible condition in clean frame.", NULL, 0);
- }
- /******
- if (dp + 1 != stackp) {
- fprintf(stderr, "Inconsistent difference: %d\n", stackp-1-dp);
- }
- *******/
- while (num--) {
- frp->nargs--;
- frp->argn -= 2;
- switch ((int)frp->argn[2].val) {
- case NUMBER:
- case VEC:
- case PARAM:
- case STRVAR:
- break;
- case AUTOVEC:
- sp = (Symbol *) (int) frp->argn[1].val;
- free(sp->name);
- Ft_free_dvector(sp->u.vec, 1, sp->size.val);
- free((char *)sp);
- break;
- case AUTOSTRVAR:
- sp = (Symbol *) (int) frp->argn[1].val;
- free(sp->name);
- free(sp->u.str);
- free((char *)sp);
- break;
- default:
- Ft_matherror("Impossible case in cleanfrp.", NULL, 0);
- }
- }
- }
-
- Code Ft_pushnull(void)
- {
- Datum d;
-
- CODE("pushnull");
- d.val = 0.0;
- Ft_push(d);
- }
-
- static void ret(void)
- {
- CODE("ret");
-
- cleanfrp(ALL); /* clean stack of all auto variables, arguments...*/
- pc = (Inst *)frp->retpc;
- stackp = frp->argn + 1;
- frp--;
- Returning = 1;
- }
-
- Code Ft_funcret(void)
- {
- Datum d;
-
- CODE("funcret");
- if (frp->sp->type == PROCSYM) {
- Ft_matherror("%s: Procedure returning value!", frp->sp->name, 0);
- }
- d = Ft_pop();
- ret();
- Ft_push(d);
- }
-
- Code Ft_procret(void)
- {
- CODE("procret");
- if (frp->sp->type == FUNCSYM) {
- Ft_matherror("%s: Function not returning value!", frp->sp->name, 0);
- }
- ret();
- }
-
- static double *getarg(void)
- {
- int which;
-
- CODE("getarg");
- which = (int)*pc++;
- PNUM(which);
- if (which > frp->nargs) {
- Ft_matherror("%s: Not enough arguments.", frp->sp->name, 0);
- }
- return(&frp->argn[2*(which - frp->nargs) - 1].val);
- }
-
- Code Ft_argpush(void)
- {
- Datum d;
-
- CODE("argpush");
- d.val = *getarg();
- Ft_push(d);
- }
-
- Code Ft_predargpush(void)
- {
- Datum d;
-
- CODE("predargpush");
- d.val = (*getarg() -= 1.0);
- Ft_push(d);
- }
-
- Code Ft_preiargpush(void)
- {
- Datum d;
-
- CODE("preiargpush");
- d.val = (*getarg() += 1.0);
- Ft_push(d);
- }
-
- Code Ft_postiargpush(void)
- {
- Datum d;
- double *dp;
-
- CODE("postiargpush");
- dp = getarg();
- d.val = *dp;
- *dp += 1.0;
- Ft_push(d);
- }
-
- Code Ft_postdargpush(void)
- {
- Datum d;
- double *dp;
-
- CODE("postiargpush");
- dp = getarg();
- d.val = *dp;
- *dp -= 1.0;
- Ft_push(d);
- }
-
- Code Ft_argassign(void)
- {
- Datum d;
-
- CODE("argassign");
- d = Ft_pop();
- Ft_push(d);
- *getarg() = d.val;
- }
-
- Code Ft_argaddassign(void)
- {
- Datum d;
-
- CODE("argaddassign");
- d = Ft_pop();
- d.val = (*getarg() += d.val);
- Ft_push(d);
- }
-
- Code Ft_argmulassign(void)
- {
- Datum d;
-
- CODE("argmulassign");
- d = Ft_pop();
- d.val = (*getarg() *= d.val);
- Ft_push(d);
- }
-
- Code Ft_argsubassign(void)
- {
- Datum d;
-
- CODE("argsubassign");
- d = Ft_pop();
- d.val = (*getarg() -= d.val);
- Ft_push(d);
- }
-
- Code Ft_argdivassign(void)
- {
- Datum d;
- extern int Ft_Check;
-
- CODE("argdivassign");
- d = Ft_pop();
- if (d.val == 0.0 && Ft_Check & INF_CHK) {
- Ft_matherror("Division by zero.", NULL, 0);
- }
- d.val = (*getarg() /= d.val);
- Ft_push(d);
- }
-
- Code Ft_pushexprtype(void)
- {
- Datum d;
-
- CODE("pushexprtype");
- d.val = NUMBER;
- Ft_push(d);
- }
-
- Code Ft_pushvectype(void)
- {
- Datum d;
-
- CODE("pushvectype");
- d.val = VEC;
- Ft_push(d);
- }
-
- Code Ft_pushstrtype(void)
- {
- Datum d;
-
- CODE("pushstrtype");
- d.val = STRVAR;
- Ft_push(d);
- }
-
- Code Ft_pushpartype(void)
- {
- Datum d;
-
- CODE("pushpartype");
- d.val = PARAM;
- Ft_push(d);
- }
-
- Code Ft_pushavectype(void)
- {
- Datum d;
-
- CODE("pushavectype");
- d.val = AUTOVEC;
- Ft_push(d);
- }
-
- Code Ft_pushastrtype(void)
- {
- Datum d;
-
- CODE("pushastrtype");
- d.val = AUTOSTRVAR;
- Ft_push(d);
- }
-
- void Ft_defnonly(int type, char *string)
- {
- switch(type) {
- case WHILE:
- if (Ft_Inbrace) return;
- Ft_matherror("`%s' used outside for or while loop.", string, 0);
- break;
- case FUNC:
- if (Ft_Indef) return;
- Ft_matherror("`%s' used outside function.", string, 0);
- break;
- case PROC:
- if (Ft_Indef) return;
- Ft_matherror("`%s' used outside procedure.", string, 0);
- break;
- default:
- Ft_matherror("Strange condition in chkfunc().", NULL, 0);
- break;
- }
- }
-
- Code Ft_argvarpush(void)
- {
- Datum d;
- int which;
-
- CODE("argvarpush");
- which = (int)*pc++;
- d.sym = frp->argn[2*(which - frp->nargs) - 1].sym;
- CODE(d.sym->name);
- Ft_push(d);
- }
-
- Code Ft_strmake(void)
- {
- Datum d;
-
- CODE("strmake");
- d.sym = Ft_geninstall("auto String", UNDEFSTRVAR, 0);
- Ft_push(d);
- }
-
- Code Ft_vecmake(void)
- {
- Datum d;
- extern int Ft_Samples;
-
- CODE("vecmake");
- d.sym = Ft_geninstall("auto VEC", UNDEFVEC, Ft_Samples);
- Ft_push(d);
- }
-
- static Inst *checkargs(Inst *start, Frame *frpp)
- {
- Datum *dp;
- int i, type, num;
-
- num = 0;
- while (start[num] != STOP) {
- num++;
- }
- if (num != frpp->nargs) {
- Ft_matherror("%s(): Argument number mismatch (%d required).",
- frpp->sp->name, num);
- }
- dp = frpp->argn; /* park it on the last type */
- start += num-1; /* park it on the last argument type */
- for (i=1-num; i<= 0; i++) {
- type = (int) dp[2*i].val;
- if (type != (int)start[i]) {
- Ft_matherror("%s(): Argument %d mismatch.", frpp->sp->name, (1-i));
- }
- }
- return(start+2); /* skip the STOP */
- }
-
- void Ft_matherror(char *s1, char *s2, int lino)
- {
- extern char Ft_Puffer[];
-
- fputs("Math error: ", stderr);
- fprintf(stderr, s1, s2, lino);
- fputc('\n', stderr);
- if (Index != ERRR)
- fprintf(stderr, "Error occurred at vector element %d.\n", Index);
- fprintf(stderr, "Command line: %s", Ft_Puffer);
- Ft_catcher(ERRR);
- }
-
- int Ft_showtable(void)
- {
- FILE *fp;
- Symbol *sp, *Ft_Symlist(void);
- extern int Ft_Interact;
- extern char Ft_Pager[];
- extern FILE *popen(const char *, const char *);
- extern Datum *stack, *stackp;
- extern Frame *frame, *frp;
- extern Inst *prog;
-
- if (Ft_Interact && *Ft_Pager) {
- if ((fp = popen(Ft_Pager, "w")) == (FILE *)NULL) {
- fprintf(stderr, "Could not open pager %s.\n", Ft_Pager);
- fp = stdout;
- }
- }
- else {
- fp = stdout;
- }
-
- fprintf(fp, "%12s%35s%10s\n", "Name", "Type", "Size");
- for (sp = Ft_Symlist(); sp != (Symbol *)0; sp = sp->next) {
- switch (sp->type) {
- case VEC:
- fprintf(fp, "%12s%35s%10d\n",
- sp->name, "VEC", sp->size.val);
- break;
- case PARAM:
- fprintf(fp, "%12s%35s%10d\n",
- sp->name, "PAR", sp->size.val);
- break;
- case BLTINSTRCONST:
- fprintf(fp, "%12s%35s%10d\n",
- sp->name, "Bltin Str Constant", strlen(sp->u.str));
- break;
- case STRCONST:
- fprintf(fp, "%12s%35s%10d\n",
- sp->name, "Str Constant", strlen(sp->u.str));
- break;
- case BLTINCONST:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "bltin constant", "1");
- break;
- case CONST:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "constant", "1");
- break;
- case BLTINVAR:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "bltin variable", "1");
- break;
- case VAR:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "variable", "1");
- break;
- case BLTINSTRVAR:
- fprintf(fp, "%12s%35s%10d\n",
- sp->name, "Bltin Str Variable", sp->size.val);
- break;
- case STRVAR:
- fprintf(fp, "%12s%35s%10d\n",
- sp->name, "Str Variable", sp->size.val);
- break;
- case BLTIN0STR:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "Str Function(void)", "1");
- break;
- case BLTIN1STR:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "Str Function(Str)", "1");
- break;
- case BLTIN2STR:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "Str Function(Str, Str)", "1");
- break;
- case BLTIN0:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "function(void)", "1");
- break;
- case BLTIN1:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "function(expr)", "1");
- break;
- case BLTIN2:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "function(expr, expr)", "1");
- break;
- case STRBLTIN2:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "function(Str, Str)", "1");
- break;
- case EFUNCSYM:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, makename(sp), "1");
- break;
- case FUNCSYM:
- fprintf(fp, "%12s%35s%10s from % 4d\n",
- sp->name, makename(sp), "1", sp->u.defn -prog);
- break;
- case EPROCSYM:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, makename(sp), "1");
- break;
- case PROCSYM:
- fprintf(fp, "%12s%35s%10s from % 4d\n",
- sp->name, makename(sp), "1", sp->u.defn -prog);
- break;
- case UNDEFSTRVAR:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "Unassigned Str Variable", "0");
- break;
- case UNDEFVAR:
- fprintf(fp, "%12s%35s%10s\n",
- sp->name, "unassigned variable", "1");
- break;
- case UNDEFVEC:
- fprintf(fp, "%12s%35s%10d\n",
- sp->name, "UNASSIGNED VEC", sp->size.val);
- break;
- default:
- /*** Why print keywords?
- fprintf(fp, "%12s%35s%10d\n", "Keyword", sp->size.val);
- ***********/
- break;
- }
- }
- fprintf(fp,
- "\nactual: Stack: % 4d/%d,\tMachine: % 4d/%d,\tFrame: % 4d/%d\n",
- (stackp-stack), NSTACK, (Ft_Progp-prog), NPROG, (frp-frame), NFRAME);
- Ft_initcode();
- fprintf(fp,
- "reset: Stack: % 4d/%d,\tMachine: % 4d/%d,\tFrame: % 4d/%d\n",
- (stackp-stack), NSTACK, (Ft_Progp-prog), NPROG, (frp-frame), NFRAME);
- if (fp != stdout) pclose(fp);
- return(0);
- }
-
- static char *makename(Symbol *sp)
- {
- char *lp;
- static char arglist[256];
- int ext = 0;
-
- arglist[0] = '\0';
- switch (sp->type) {
- case EFUNCSYM:
- strcpy(arglist, " ext.");
- ext = 1;
- case FUNCSYM:
- strcat(arglist, " function(");
- break;
- case EPROCSYM:
- strcpy(arglist, " ext.");
- ext = 1;
- case PROCSYM:
- strcat(arglist, " procedure(");
- break;
- default:
- Ft_matherror("%s: Unknown function type %d.", "makename",
- sp->type);
- break;
- }
- if (ext) {
- char *cp;
-
- cp = sp->size.vals;
- while (*cp) /* go at the end */
- cp++;
-
- while (--cp >= sp->size.vals) { /* come back */
- switch (*cp) {
- case PROTO_VEC:
- strcat(arglist, "VEC, ");
- break;
- case PROTO_VAL:
- strcat(arglist, "expr, ");
- break;
- case PROTO_PAR:
- strcat(arglist, "PAR, ");
- break;
- case PROTO_STR:
- strcat(arglist, "Str, ");
- break;
- default:
- Ft_matherror("%s: Unknown case %d.", "makename", *cp);
- break;
- }
- }
- }
- else {
- Inst *pp = sp->u.defn;
-
- while (*pp != STOP) {
- switch ((int) *pp) {
- case VEC:
- strcat(arglist, "VEC, ");
- break;
- case NUMBER:
- strcat(arglist, "expr, ");
- break;
- case PARAM:
- strcat(arglist, "PAR, ");
- break;
- case STRVAR:
- strcat(arglist, "Str, ");
- break;
- default:
- Ft_matherror("%s: Unknown case %d.", "makename", (int)*pp);
- break;
- }
- pp++;
- }
- }
- lp = arglist + strlen(arglist) - 2;
- *lp++ = ')';
- *lp = '\0';
-
- return(arglist);
- }
-
-